package api

import (
	"fmt"
	"log"
	"net/http"

	"gitee.com/rdor/pod-filebrowser/pkg/fs"
	"gitee.com/rdor/pod-filebrowser/pkg/k8s"
	"gitee.com/rdor/pod-filebrowser/pkg/types"
	"github.com/gin-gonic/gin"
)

type Server struct {
	k8sClient *k8s.Client
	fs        *fs.K8sFS
}

func NewServer() (*Server, error) {
	client, err := k8s.NewClient()
	if err != nil {
		return nil, err
	}

	return &Server{
		k8sClient: client,
	}, nil
}

func (s *Server) Run() error {
	r := gin.Default()
	// Static files
	r.StaticFS("/static", http.Dir("./web/static"))
	r.GET("/", func(c *gin.Context) {
		c.Redirect(http.StatusMovedPermanently, "/static/index.html")
	})
	// API routes
	api := r.Group("/api")
	{
		api.GET("/namespaces", s.ListNamespaces)
		api.GET("/namespaces/:namespace/pods", s.ListPods)
		api.GET("/namespaces/:namespace/pods/:pod/containers", s.ListContainers)
		api.POST("/mount", s.MountContainer)
	}

	fmt.Println("Server is running on http://localhost:8081")
	return r.Run("0.0.0.0:8081")
}

func (s *Server) ListNamespaces(c *gin.Context) {
	namespaces, err := s.k8sClient.ListNamespaces()
	if err != nil {
		c.JSON(http.StatusInternalServerError, types.Response{
			Status:  "error",
			Message: err.Error(),
		})
		return
	}
	log.Println("====", namespaces)

	c.JSON(http.StatusOK, types.Response{
		Status: "success",
		Data:   namespaces,
	})
}

func (s *Server) ListPods(c *gin.Context) {
	namespace := c.Param("namespace")
	pods, err := s.k8sClient.ListPods(namespace)
	if err != nil {
		c.JSON(http.StatusInternalServerError, types.Response{
			Status:  "error",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, types.Response{
		Status: "success",
		Data:   pods,
	})
}

func (s *Server) ListContainers(c *gin.Context) {
	namespace := c.Param("namespace")
	podName := c.Param("pod")

	containers, err := s.k8sClient.ListContainers(namespace, podName)
	if err != nil {
		c.JSON(http.StatusInternalServerError, types.Response{
			Status:  "error",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, types.Response{
		Status: "success",
		Data:   containers,
	})
}

func (s *Server) MountContainer(c *gin.Context) {
	var req types.MountRequest
	var err error
	if err = c.BindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, types.Response{
			Status:  "error",
			Message: err.Error(),
		})
		return
	}

	// Create or update the FUSE filesystem
	if s.fs == nil {
		// Create a new FUSE filesystem
		s.fs, err = fs.NewK8sFS(s.k8sClient, req.Namespace, req.PodName, req.ContainerName)
		if err != nil {
			c.JSON(http.StatusInternalServerError, types.Response{
				Status:  "error",
				Message: fmt.Sprintf("failed to create filesystem: %v", err),
			})
			return
		}
	} else {
		// Update the existing FUSE filesystem with new parameters
		if err := s.fs.Update(req.Namespace, req.PodName, req.ContainerName); err != nil {
			c.JSON(http.StatusInternalServerError, types.Response{
				Status:  "error",
				Message: fmt.Sprintf("failed to update filesystem: %v", err),
			})
			return
		}
	}
	err = s.fs.Mount()
	if err != nil {
		log.Printf("Failed to mount filesystem: %v", err)
		c.JSON(http.StatusInternalServerError, types.Response{
			Status:  "error",
			Message: fmt.Sprintf("failed to Mount: %v", err),
		})
		return
	}
	log.Println("Container filesystem mounted successfully")
}
